<template>
  <div v-loading="loading" class="AddOrUpdate_main add_container">
    <div class="main_main">
      <div id="ProcessPlanning_ID">
        <butterfly-vue
          :canvas-data="graphData"
          :canvas-conf="canvasConf"
        />
      </div>
    </div>
    <div v-if="$store.state.engineeringManage.showDetail" class="main_bottom">
      <!-- <el-button v-if="graphData.nodes.length==0" @click="chooseRootMaterial">选择物料</el-button> -->
      <el-button type="cancel" @click.stop="cancel">取消</el-button>
      <el-button @click.stop="onSubmit('0')">保存</el-button>
      <el-button @click.stop="onSubmit('1')">提交</el-button>
    </div>
  </div>
</template>

<script>
import { ButterflyVue } from 'butterfly-vue'
import MaterialNode from './components/nodes/MaterialNode.vue'
import ProcessNode from './components/nodes/ProcessNode.vue'
import { list as getProcessList } from '@/api/engineeringManage/processManage'
import { addOrEdit, addOrUpdate, getInfo, getInfoYg } from '@/api/engineeringManage/processRequirementNew'
import { getByTableAndColumn } from '@/api/system/codeRule'
import { mapGetters, mapState } from 'vuex'
import ChooseRootMaterial from './components/nodes/ChooseRootMaterial.vue'
import { state } from '@/api/system/personalCenter'
var id = 0
var nodeId = 0
var edgeId = 0
export default {
  name: 'ProcessPlanning',
  components: {
    ButterflyVue
  },
  props: {
    layerid: {},
    id: {},
    showDetail: {}
  },
  data() {
    return {
      loading: false,
      processList: [], // 所有工序
      formData: {
        id: undefined,
        code: '自动生成',
        fileName: '',
        fileRealName: '',
        fileUrl: '',
        remark: undefined,
        versionCode: ''
      },
      canvasConf: {
        disLinkable: true, // 可删除连线
        linkable: true, // 可连线
        draggable: true, // 可拖动
        zoomable: true, // 可放大
        moveable: true, // 可平移
        layout: {
          type: 'dagreLayout',
          options: {
            rankdir: 'TB',
            nodesep: 80,
            ranksep: 20,
            controlPoints: false
          }
        },
        theme: {
          edge: {
            shapeType: 'AdvancedBezier'
            // shapeType: 'Bezier'
          }
        }
      },
      watchData: {},
      graphData: {
        groups: [],
        nodes: [],
        edges: []
      }
    }
  },
  computed: {
    ...mapState('engineeringManage', {
      addProcessData: state => state.addProcessData,
      addMaterialData: state => state.addMaterialData,
      updateNodeData: state => state.updateNodeData,
      deleteNodeData: state => state.deleteNodeData,
      processNodeData: state => state.processNodeData
    })
  },
  watch: {
    addProcessData: { // 添加工序的回调
      handler() {
        if (this.addProcessData) {
        // 如果已经存在工序了，则进行替换
          if (this.graphData.edges.some(item => item.source == this.addProcessData.fromData.id)) {
            const oldNodeId = this.graphData.edges.filter(item => item.source == this.addProcessData.fromData.id)[0].target
            this.graphData.nodes.forEach(item => {
              if (item.id == oldNodeId) {
                const newEdgeIdElement = this.$deepClone(this.addProcessData.toData)
                newEdgeIdElement.nodeId = item.data.nodeId
                item.data = newEdgeIdElement
              }
            })
          } else {
          // 如果不存在工序，则进行添加
            let newNodeId = ''
            let newEdgeId = ''

            newNodeId = id++ + ''
            newEdgeId = id++ + ''
            const newEdgeIdElement = this.$deepClone(this.addProcessData.toData)
            newEdgeIdElement.nodeId = newNodeId
            this.graphData.nodes.push(
              {
                id: newNodeId,
                data: newEdgeIdElement,
                render: ProcessNode
              }
            )
            this.graphData.edges.push(
              {
                id: newEdgeId,
                source: this.addProcessData.fromData.id,
                target: newNodeId,
                type: 'node'
              }
            )
          }

          this.$nextTick(() => {
            this.$store.state.engineeringManage.addProcessData = undefined
            this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
          })
        }
      },
      deep: true,
      immediate: true
    },
    addMaterialData: { // 添加物料的回调
      handler() {
        if (this.addMaterialData) {
          let newNodeId = ''
          let newEdgeId = ''
          for (const newEdgeIdElement of this.addMaterialData.toData) {
            newNodeId = id++ + ''
            newEdgeId = id++ + ''

            newEdgeIdElement.nodeId = newNodeId

            newEdgeIdElement.requisitionOrReturn = '1'
            newEdgeIdElement.demandNumber = '1'
            newEdgeIdElement.productBySelf = '1'
            newEdgeIdElement.toInspect = '1'
            newEdgeIdElement.toWms = '1'

            this.graphData.nodes.push(
              {
                id: newNodeId,
                data: newEdgeIdElement,
                render: MaterialNode,
                processList: this.processList
              }
            )
            this.graphData.edges.push(
              {
                id: newEdgeId,
                source: this.addMaterialData.fromData.id,
                target: newNodeId,
                type: 'node'
              }
            )
          }

          this.$nextTick(() => {
            this.$store.state.engineeringManage.addMaterialData = undefined
            this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
          })
        }
      },
      deep: true,
      immediate: true
    },
    updateNodeData: {
      deep: true,
      immediate: true,
      handler() {
        if (this.updateNodeData) {
          this.graphData.nodes.forEach(item => {
            if (item.data.nodeId == this.updateNodeData.nodeId) {
              Object.keys(this.updateNodeData).forEach(key => {
                item.data[key] = JSON.parse(JSON.stringify(this.updateNodeData[key]))
              })
            }
          })
          this.$nextTick(() => {
            console.log(this.graphData)
            this.$store.state.engineeringManage.updateNodeData = undefined
            this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
          })
        }
      }
    },
    deleteNodeData: { // 删除节点数据的回调
      handler() {
        if (this.deleteNodeData) {
          const deleteNodeId = this.deleteNodeData.nodeId
          // 递归找出这个节点下面的所有关联的子节点
          const results = []
          this.findChildNodes(results, deleteNodeId)
          // Node节点中删除相关的节点
          const cacheNodes = this.$deepClone(this.graphData.nodes)
          for (const cacheNode of cacheNodes) {
            if (results.includes(cacheNode.id)) {
              this.graphData.nodes.splice(this.graphData.nodes.findIndex(item => item.id == cacheNode.id), 1)
            }
          }

          // Edge线段中，删除相关的线段
          const cacheEdges = this.$deepClone(this.graphData.edges)
          for (const cacheEdge of cacheEdges) {
            if (results.includes(cacheEdge.target) || results.includes(cacheEdge.source)) {
              this.graphData.edges.splice(this.graphData.edges.findIndex(item => item.id == cacheEdge.id), 1)
            }
          }

          this.$nextTick(() => {
            this.$store.state.engineeringManage.deleteNodeData = undefined
            this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
          })
        }
      }
    },
    deep: true,
    immediate: true
  },
  mounted() {
    const _this = this
    // this.$nextTick(() => {
    //   this.initDag()
    // })
    // setTimeout(() => {
    //   _this.initDag()
    // }, 1000)
    this.getProcessList()
    this.getRuleCode()
    if (this.id) { // 编辑
      this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
      id = 999
      this.getInfo()
    } else { // 新增
      setTimeout(() => {
        this.chooseRootMaterial()
      }, 200)

      this.$store.state.engineeringManage.showDetail = true
    }
  },
  beforeDestroy() {
    this.$store.dispatch('engineeringManage/changeData', {})
  },
  methods: {
    getRuleCode() {
      getByTableAndColumn({ table: 'engineering_requirement', column: 'code' }).then(res => {
        if (res.data && res.data.status === '1') { // 如果有编码规则
          this.$store.state.engineeringManage.isEnable = true
          if (this.id) { // 编辑
            this.$store.state.engineeringManage.isAllowEdit = res.data.allowEdit == '1'
          } else { // 新增
            this.$store.state.engineeringManage.isAllowEdit = false
            this.formData.code = '自动生成'
          }
        } else { // 没有编码规则
          this.$store.state.engineeringManage.isEnable = false
        }
      })
    },
    getInfo() {
      const getInfoCallback = (res) => {
        this.$store.state.engineeringManage.showDetail = this.showDetail
        Object.keys(this.formData).forEach(key => {
          this.formData[key] = res.data[key]
        })
        this.setData(res.data.data)
        this.$set(this.graphData.nodes[0].data, 'code', res.data.code)
        this.$set(this.graphData.nodes[0].data, 'versionCode', res.data.versionCode)
        this.$set(this.graphData.nodes[0].data, 'isEqual', res.data.isEqual)
        console.log('graphData', this.graphData)
        this.$nextTick(() => {
          this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
          // this.$store.commit('engineeringManage/CHANGE_SETTING', this.$deepClone(this.graphData))
        })
      }

      if (this.$parent.pageId === '银光工艺要求') {
        getInfoYg(this.id).then(res => {
          getInfoCallback(res)
        })
      } else {
        getInfo(this.id).then(res => {
          getInfoCallback(res)
        })
      }
    },
    setData(data) {
      const queue = []
      for (let i = 0; i < data.length; i++) {
        queue.push({ node: data[i], parentId: null })
      }
      while (queue.length > 0) {
        const { node, parentId } = queue.shift()
        nodeId++
        const currentNodeId = nodeId.toString()
        // 给 engineeringProcessId 赋值并删除该属性
        const engineeringProcessId = node.engineeringProcessId
        const engineeringProcessName = node.engineeringProcessName
        delete node.engineeringProcessId
        delete node.engineeringProcessName
        this.graphData.nodes.push({ id: currentNodeId, data: { ...node, nodeId: currentNodeId }, render: MaterialNode })
        if (parentId) {
          edgeId++
          this.graphData.edges.push({ id: edgeId.toString(), source: (Number(parentId) + 1) + '', target: currentNodeId, type: 'node' })
        }
        if (engineeringProcessId) {
          nodeId++
          const processNodeId = nodeId.toString()
          this.graphData.nodes.push({ id: processNodeId, data: { id: engineeringProcessId, nodeId: processNodeId, name: engineeringProcessName, standardWorkTime: node.standardWorkTime, workTimePrice: node.workTimePrice, unitPriceOfPiecework: node.unitPriceOfPiecework }, render: ProcessNode })
          edgeId++
          this.graphData.edges.push({ id: edgeId.toString(), source: currentNodeId, target: processNodeId, type: 'node' })
        }
        if (node.children) {
          for (let j = 0; j < node.children.length; j++) {
            queue.push({ node: node.children[j], parentId: currentNodeId })
          }
        }
      }
    },
    onSubmit(num) {
      if (!this.graphData.nodes[0].data.code && !this.formData.code) {
        this.$message.warning('工艺编码不能为空')
        return
      }
      if (!this.graphData.nodes[0].data.versionCode) {
        this.$message.warning(`请点击（${this.graphData.nodes[0].data.materialCode}/${this.graphData.nodes[0].data.materialName}）旁边的编辑按钮，输入版本号`)
        return
      }
      console.log('this.graphData', this.graphData)
      const data = this.$deepClone(this.graphData)
      const nodes = this.$deepClone(data.nodes)
      const edges = this.$deepClone(data.edges)
      console.log('node', nodes)
      const nodeTrees = this.$deepClone(this.buildTree(nodes, edges))
      console.log('nodeTrees====>', nodeTrees)
      this.mergeChildren(nodeTrees)
      delete data.nodes[0].id
      this.formData.versionCode = data.nodes[0].data.versionCode
      if (this.id) {
        this.formData.code = data.nodes[0].data.code
      }
      addOrUpdate({ data: nodeTrees, ...data.nodes[0].data, ...this.formData, status: num }).then(res => {
        this.$message.success('操作成功')
        this.$layer.close(this.layerid)
        this.$parent.getList()
        const allPopover = document.querySelectorAll('.el-popper')
        allPopover.forEach(element => {
          element.style.display = 'none'
        })
        console.log(111111)
      })
    },
    buildTree(nodes, edges) {
      const nodeMap = new Map()
      // 使用节点的 id 创建节点映射
      for (const node of nodes) {
        nodeMap.set(node.id, { ...node.data, children: [] })
      }
      // 构建树结构
      for (const edge of edges) {
        var sourceNode = nodeMap.get(edge.source)
        var targetNode = nodeMap.get(edge.target)
        // 如果找到源节点和目标节点，则将目标节点添加为源节点的子节点
        if (sourceNode && targetNode) {
          sourceNode.children.push(targetNode)
        }
      }
      // 查找根节点
      const rootNodes = nodes.filter((node) => !edges.some((edge) => edge.target === node.id))
      return rootNodes.map((rootNode) => nodeMap.get(rootNode.id))
    },
    mergeChildren(data) {
      for (let i = 0; i < data.length; i++) {
        data[i]['nodeKey'] = JSON.parse(JSON.stringify(data[i].id))
        delete data[i].id
        if (data[i].children) {
          this.mergeChildren(data[i].children)
          for (let j = 0; j < data[i].children.length; j++) {
            if (!data[i].children[j].materialId) {
              data[i].children = data[i].children.concat(data[i].children[j].children)
              data[i].engineeringProcessName = data[i].children[j].name
              data[i].engineeringProcessId = data[i].children[j].nodeKey
              data[i].standardWorkTime = data[i].children[j].standardWorkTime
              data[i].workTimePrice = data[i].children[j].workTimePrice
              data[i].unitPriceOfPiecework = data[i].children[j].unitPriceOfPiecework
              data[i].children.splice(j, 1)
              j--
            }
          }
        }
      }
    },
    cancel() {
      this.$layer.close(this.layerid)// 关闭弹框
      const allPopover = document.querySelectorAll('.el-popper')
      allPopover.forEach(element => {
        element.style.display = 'none'
      })
    },
    getProcessList() {
      getProcessList({ status: 1 }).then(res => {
        // this.processList = res.data
        this.$store.state.engineeringManage.processNodeData = res.data
      })
    },
    chooseRootMaterial() {
      this.$layer.iframe({
        // 弹框
        content: {
          content: ChooseRootMaterial, // 传递的组件对象
          parent: this, // 当前的vue对象
          data: {
            selectedRow: [],
            excludeSelect: []
          } // 当前主物料和当前点击的父级物料不能勾选
        },
        area: ['1320px', '700px'],
        title: '选择物料', // 标题
        shadeClose: false, // 点击遮罩是否关闭
        closeable: false // 是否可关闭
      })
    },
    chooseRootMaterialCallBack(item) {
      const nodeId = id++ + ''
      item.nodeId = nodeId
      item.productBySelf = '1'
      item.toInspect = '1'
      item.toWms = '1'
      item.demandNumber = '1'
      item.isEqual = '0'
      this.graphData.nodes.push(
        {
          id: nodeId,
          data: item,
          render: MaterialNode
        }
      )

      this.$nextTick(() => {
        this.$store.state.engineeringManage.graphData = this.$deepClone(this.graphData)
      })
    },
    findChildNodes(results, nodeId) { // 查找子节点
      results.push(nodeId)
      const cacheEdges = this.$deepClone(this.graphData.edges)
      const childNodes = cacheEdges.filter(item => item.source == nodeId)
      if (childNodes.length > 0) {
        for (const childNode of childNodes) {
          this.findChildNodes(results, childNode.target)
        }
      }
    }

  }
}
</script>

<style lang="less" scoped>
.main_main{
  display: flex;
  background-color: rgba(0,0,0,0.1);
  padding-top:0;
}
#ProcessPlanning_ID{
  flex: 1;
}
</style>
